package com.sanq.product.books.controller;

import com.sanq.product.books.config.Redis;
import com.sanq.product.books.entity.vo.CollectionVo;
import com.sanq.product.books.entity.vo.DiscussVo;
import com.sanq.product.books.entity.vo.UsersVo;
import com.sanq.product.books.service.CollectionService;
import com.sanq.product.books.service.DiscussService;
import com.sanq.product.books.service.UsersService;
import com.sanq.product.books.utils.WebUtil;
import com.sanq.product.config.utils.annotation.LogAnnotation;
import com.sanq.product.config.utils.date.LocalDateUtils;
import com.sanq.product.config.utils.entity.Response;
import com.sanq.product.config.utils.string.DigestUtil;
import com.sanq.product.config.utils.string.MatcherUtil;
import com.sanq.product.config.utils.string.StringUtil;
import com.sanq.product.config.utils.web.JsonUtil;
import com.sanq.product.redis.service.JedisPoolService;
import com.sanq.product.security.annotation.IgnoreSecurity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping("/app/users")
public class UsersController {

    @Resource
    private UsersService usersService;
    @Resource
    private JedisPoolService jedisPoolService;
    @Resource
    private CollectionService collectionService;
    @Resource
    private DiscussService discussService;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @IgnoreSecurity
    @LogAnnotation(description = "登陆")
    @PostMapping(value = "/login")
    public Response login(HttpServletRequest request, @RequestBody UsersVo usersVo) {

        if (null == usersVo)
            return new Response().failure();

        UsersVo params = new UsersVo();

        if ("pwd".equals(usersVo.getType())) {
            if (StringUtil.isEmpty(usersVo.getLoginName()))
                return new Response().failure("请输入账号");

            if (MatcherUtil.isEmail(usersVo.getLoginName())) {
                params.setEmail(usersVo.getLoginName());
            } else if (MatcherUtil.isTelephone(usersVo.getLoginName()))
                params.setTel(DigestUtil.getInstance().encode(usersVo.getLoginName()));

            if (StringUtil.isEmpty(usersVo.getLoginPwd()))
                return new Response().failure("请输入密码");

            params.setLoginPwd(DigestUtil.getInstance().md5(usersVo.getLoginPwd()));
        } else {
            if (StringUtil.isEmpty(usersVo.getTel()))
                return new Response().failure("请输入手机号");

            if (StringUtil.isEmpty(usersVo.getCode()))
                return new Response().failure("请输入验证码");

            params.setTel(DigestUtil.getInstance().encode(usersVo.getTel()));
            String code = jedisPoolService.get(Redis.ReplaceKey.getTelCode(usersVo.getTel()));

            if (!usersVo.getCode().equals(code))
                return new Response().failure("验证码输入不正确，请重新输入");
        }

        List<UsersVo> list = usersService.findList(params);

        if (list == null || list.isEmpty())
            return new Response().failure("请检查账户或密码");

        params = list.get(0);

        // 修改登陆时间
        final UsersVo u = params;
        taskExecutor.execute(() -> {
            u.setLastLoginTime(LocalDateUtils.nowTime());
            usersService.update(u, u.getId());
        });

        params.setLoginPwd("");

        String token = StringUtil.uuid();

        jedisPoolService.set(Redis.ReplaceKey.getTokenUser(token), JsonUtil.obj2Json(params));

        return new Response().success(token);
    }

    @IgnoreSecurity
    @LogAnnotation(description = "注册")
    @PostMapping(value = "/reg")
    public Response reg(HttpServletRequest request, @RequestBody UsersVo usersVo) {

        if (null == usersVo)
            return new Response().failure();

        String code = jedisPoolService.get(Redis.ReplaceKey.getTelCode(usersVo.getTel()));

        if (StringUtil.isEmpty(usersVo.getTel()))
            return new Response().failure("请输入手机号");

        if (StringUtil.isEmpty(usersVo.getCode()))
            return new Response().failure("请输入验证码");

        List<UsersVo> list = usersService.findList(usersVo);

        if (list != null && list.size() > 0)
            return new Response().failure("当前手机号已经存在");

        if (!usersVo.getCode().equals(code))
            return new Response().failure("验证码输入不正确，请重新输入");

        usersVo.setTel(DigestUtil.getInstance().encode(usersVo.getTel()));

        usersVo.setNickName("书友" + LocalDateUtils.nowTime().getTime());


        int result = usersService.save(usersVo);

        return result != 0 ? new Response().success("注册成功") : new Response().failure("注册失败");
    }

    @LogAnnotation(description = "通过token获取用户信息")
    @GetMapping(value = "/getUsersForCache")
    public Response getUsersForCache(HttpServletRequest request) {

        UsersVo usersVo = JsonUtil.json2Obj(jedisPoolService.get(Redis.ReplaceKey.getTokenUser(WebUtil.getToken(request))), UsersVo.class);

        CollectionVo collectionVo = new CollectionVo();
        collectionVo.setUserId(usersVo.getId());
        usersVo.setCollectionCount(collectionService.findCount(collectionVo));

        //书评
        DiscussVo discussVo = new DiscussVo();
        discussVo.setUserId(usersVo.getId());
        usersVo.setDiscussCount(discussService.findCount(discussVo));

        //vip 天数
//        if(usersVo.getIsVip() == 1) {
//            usersVo.setVipEndDay(StringUtil.toInteger((LocalDateUtils.nowTime().getTime() - usersVo.getVipEndTime().getTime()) / 1000 / 3600 / 24));
//        }

        return usersVo != null ? new Response().success(usersVo) : new Response().failure();
    }

    @LogAnnotation(description = "修改用户信息")
    @PostMapping(value = "/update")
    public Response update(HttpServletRequest request, @RequestBody UsersVo usersVo) {

        UsersVo oldUsersVo = JsonUtil.json2Obj(jedisPoolService.get(Redis.ReplaceKey.getTokenUser(usersVo.getToken())), UsersVo.class);

        if(usersVo == null)
            return new Response().failure();

        oldUsersVo.setNickName(usersVo.getNickName());
        oldUsersVo.setSex(usersVo.getSex());
        oldUsersVo.setAvator(usersVo.getAvator());

        int result = usersService.update(oldUsersVo, oldUsersVo.getId());

        if(1 == result) {
            jedisPoolService.set(Redis.ReplaceKey.getTokenUser(usersVo.getToken()), JsonUtil.obj2Json(usersService.findById(oldUsersVo.getId())));
            return new Response().success();
        }

        return new Response().failure();
    }
}